Initial work in mapping EDT and Waze incident data
Started 2017-11-28
Ideas:
- Frequency of events - histograms of different Waze event frequencies within a day, for different event types (accident, jam, weather hazard, road closed), and same for EDT incident count frequencies within a day
- Incident type by time of day
- Duration of incidents
- Spatial overlay of events - similar to Lia’s slider idea, make a figure which builds up hotspots of Waze and EDT by day
- Spatiotemporal join - Paul’s 2x2 for time (early, laggy) and space (near, far) matching of EDT and Waze, by type. In the future, using data snapped to HPMS, use roadway classification as well, or could use day of week.
# Read in libraries and set working directory
knitr::opts_chunk$set(echo = T, warning=F, message=F)
options(width = 2400, stringsAsFactors = F)
library(ggplot2)
library(tidyverse)
library(maps) # for mapping base layers
library(reshape)
library(DT) # for datatable
# devtools::install_github("ropensci/plotly") # for latest version
library(plotly) # do after ggplot2
library(sp)
library(maptools) # readShapePoly() and others
library(mapproj) # for coord_map()
library(rgdal) # for readOGR(), needed for reading in ArcM shapefiles
library(rgeos) # for gIntersection, to clip two shapefiles
library(raster)
wazedir <- "W:/SDI Pilot Projects/Waze/Working Documents"
knitr::opts_knit$set(root.dir = wazedir)
# Initial run: Start with the projected EDT and Waze data that Lia has prepared. It appears this is just the one week of August data for MD; use aa pilot, expand to other periods after. Clean these data and save as .RData. If already done, load the processed data.
if(length(grep('EDT_Waze.RData', dir())) < 1){
waz.shp <- readOGR(dsn = ".", "Waze_sample_projected")
edt.shp <- readOGR(dsn = ".", "EDT_sample_projected")
# Fix time values: convert pub_millis to usable POSIX date class
waz.shp$time <- as.POSIXct(waz.shp$pub_millis/1000, origin = "1970-01-01", tz="America/New_York")
# Convert crashdate and time in EDT to POSIX
edt.time <- paste(as.character(edt.shp$CrashDate), " ",
edt.shp$HourofDay, ":",
formatC(as.numeric(as.character(edt.shp$MinuteofDa)), width = 2, flag = "0"), sep = "")
edt.shp$time <- strptime(edt.time, format = "%Y/%m/%d %H:%M", tz="America/New_York")
# Read in county data from Census
counties <- readOGR("CensusCounty/.")
md_counties <- counties[counties$STATEFP == 24,]
# Save imported waze and EDT files as .RData for faster import after the first time
save(file = "EDT_Waze.RData", list = c("waz.shp", "edt.shp", "md_counties"))
} else { load('EDT_Waze.RData') }
Initial mapping work
counties <- map_data("county", "maryland")
waz.shp$tooltiptext <- with(waz.shp@data, paste(city, alert_type, time, sep = "\n"))
waz.shp$tooltiptext <- sub("NA", "", waz.shp$tooltiptext)
edt.shp$tooltiptext <- with(edt.shp@data, paste(County, HighestInj, time, sep = "\n"))
edt.shp$tooltiptext <- sub("NA", "", edt.shp$tooltiptext)
map.p <- ggplot() +
ggtitle("2017-08-01 Spatial Overlay") +
geom_polygon(data = counties, aes(x = long, y = lat, group = group),
color = "white", fill = "grey80") + theme_void() +
coord_fixed(1.3) +
geom_point(data = waz.shp[format(waz.shp$time, "%d") == "01",]@data, # 2017-08-01 first
aes(
x = longitude,
y = latitude,
color = alert_type,
text = tooltiptext),
shape = 16) +
geom_point(data = edt.shp[format(edt.shp$time, "%d") == "01",]@data, # 2017-08-01 first
aes(
x = GPSLong_Ne,
y = GPSLat,
text = tooltiptext,
color = 'EDT'),
shape = 16) +
scale_color_brewer(palette = "Set1",
name = "Waze Alert Type and EDT Crash")
ggplotly(map.p, tooltip = "text", width = 1000)
Interactive table of Waze events by day
# make a table of frequency of alert_type by day
freq.tab <- aggregate(uuid ~ format(time, "%d") + alert_type,
FUN = length,
data = waz.shp@data)
datatable(freq.tab,
filter = 'top',
colnames = c("Day" = 1, "Alert Type" = 2, "Count"= 3),
rownames = F,
options = list(dom = "ftip"))
LS0tDQp0aXRsZTogIkVEVCArIFdhemUgSm9pbmluZyINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQpJbml0aWFsIHdvcmsgaW4gbWFwcGluZyBFRFQgYW5kIFdhemUgaW5jaWRlbnQgZGF0YQ0KDQpTdGFydGVkIDIwMTctMTEtMjgNCg0KSWRlYXM6DQoNCi0gRnJlcXVlbmN5IG9mIGV2ZW50cyAtIGhpc3RvZ3JhbXMgb2YgZGlmZmVyZW50IFdhemUgZXZlbnQgZnJlcXVlbmNpZXMgd2l0aGluIGEgZGF5LCBmb3IgZGlmZmVyZW50IGV2ZW50IHR5cGVzIChhY2NpZGVudCwgamFtLCB3ZWF0aGVyIGhhemFyZCwgcm9hZCBjbG9zZWQpLCBhbmQgc2FtZSBmb3IgRURUIGluY2lkZW50IGNvdW50IGZyZXF1ZW5jaWVzIHdpdGhpbiBhIGRheQ0KLSBJbmNpZGVudCB0eXBlIGJ5IHRpbWUgb2YgZGF5DQotIER1cmF0aW9uIG9mIGluY2lkZW50cw0KLSBTcGF0aWFsIG92ZXJsYXkgb2YgZXZlbnRzIC0gc2ltaWxhciB0byBMaWEncyBzbGlkZXIgaWRlYSwgbWFrZSBhIGZpZ3VyZSB3aGljaCBidWlsZHMgdXAgaG90c3BvdHMgb2YgV2F6ZSBhbmQgRURUIGJ5IGRheQ0KLSBTcGF0aW90ZW1wb3JhbCBqb2luIC0gUGF1bCdzIDJ4MiBmb3IgdGltZSAoZWFybHksIGxhZ2d5KSBhbmQgc3BhY2UgKG5lYXIsIGZhcikgbWF0Y2hpbmcgb2YgRURUIGFuZCBXYXplLCBieSB0eXBlLiBJbiB0aGUgZnV0dXJlLCB1c2luZyBkYXRhIHNuYXBwZWQgdG8gSFBNUywgdXNlIHJvYWR3YXkgY2xhc3NpZmljYXRpb24gYXMgd2VsbCwgb3IgY291bGQgdXNlIGRheSBvZiB3ZWVrLg0KDQoNCmBgYHtyIHNldHVwLCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9DQojIFJlYWQgaW4gbGlicmFyaWVzIGFuZCBzZXQgd29ya2luZyBkaXJlY3RvcnkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVCwgd2FybmluZz1GLCBtZXNzYWdlPUYpDQpvcHRpb25zKHdpZHRoID0gMjQwMCwgc3RyaW5nc0FzRmFjdG9ycyA9IEYpDQoNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShtYXBzKSAjIGZvciBtYXBwaW5nIGJhc2UgbGF5ZXJzDQpsaWJyYXJ5KHJlc2hhcGUpDQpsaWJyYXJ5KERUKSAjIGZvciBkYXRhdGFibGUNCiMgZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJyb3BlbnNjaS9wbG90bHkiKSAjIGZvciBsYXRlc3QgdmVyc2lvbg0KbGlicmFyeShwbG90bHkpICMgZG8gYWZ0ZXIgZ2dwbG90Mg0KbGlicmFyeShzcCkNCmxpYnJhcnkobWFwdG9vbHMpICMgcmVhZFNoYXBlUG9seSgpIGFuZCBvdGhlcnMNCmxpYnJhcnkobWFwcHJvaikgIyBmb3IgY29vcmRfbWFwKCkNCmxpYnJhcnkocmdkYWwpICMgZm9yIHJlYWRPR1IoKSwgbmVlZGVkIGZvciByZWFkaW5nIGluIEFyY00gc2hhcGVmaWxlcw0KbGlicmFyeShyZ2VvcykgIyBmb3IgZ0ludGVyc2VjdGlvbiwgdG8gY2xpcCB0d28gc2hhcGVmaWxlcw0KbGlicmFyeShyYXN0ZXIpDQoNCndhemVkaXIgPC0gIlc6L1NESSBQaWxvdCBQcm9qZWN0cy9XYXplL1dvcmtpbmcgRG9jdW1lbnRzIg0Ka25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSB3YXplZGlyKSANCmBgYA0KDQpgYGB7ciBkYXRhaW1wb3J0fQ0KIyBJbml0aWFsIHJ1bjogU3RhcnQgd2l0aCB0aGUgcHJvamVjdGVkIEVEVCBhbmQgV2F6ZSBkYXRhIHRoYXQgTGlhIGhhcyBwcmVwYXJlZC4gSXQgYXBwZWFycyB0aGlzIGlzIGp1c3QgdGhlIG9uZSB3ZWVrIG9mIEF1Z3VzdCBkYXRhIGZvciBNRDsgdXNlIGFhIHBpbG90LCBleHBhbmQgdG8gb3RoZXIgcGVyaW9kcyBhZnRlci4gQ2xlYW4gdGhlc2UgZGF0YSBhbmQgc2F2ZSBhcyAuUkRhdGEuIElmIGFscmVhZHkgZG9uZSwgbG9hZCB0aGUgcHJvY2Vzc2VkIGRhdGEuDQoNCmlmKGxlbmd0aChncmVwKCdFRFRfV2F6ZS5SRGF0YScsIGRpcigpKSkgPCAxKXsNCiAgd2F6LnNocCA8LSByZWFkT0dSKGRzbiA9ICIuIiwgIldhemVfc2FtcGxlX3Byb2plY3RlZCIpDQogIGVkdC5zaHAgPC0gcmVhZE9HUihkc24gPSAiLiIsICJFRFRfc2FtcGxlX3Byb2plY3RlZCIpDQogIA0KICAjIEZpeCB0aW1lIHZhbHVlczogY29udmVydCBwdWJfbWlsbGlzIHRvIHVzYWJsZSBQT1NJWCBkYXRlIGNsYXNzDQogIHdhei5zaHAkdGltZSA8LSBhcy5QT1NJWGN0KHdhei5zaHAkcHViX21pbGxpcy8xMDAwLCBvcmlnaW4gPSAiMTk3MC0wMS0wMSIsIHR6PSJBbWVyaWNhL05ld19Zb3JrIikNCiAgIyBDb252ZXJ0IGNyYXNoZGF0ZSBhbmQgdGltZSBpbiBFRFQgdG8gUE9TSVgNCiAgZWR0LnRpbWUgPC0gcGFzdGUoYXMuY2hhcmFjdGVyKGVkdC5zaHAkQ3Jhc2hEYXRlKSwgIiAiLA0KICAgICAgICAgICAgICAgICAgICBlZHQuc2hwJEhvdXJvZkRheSwgIjoiLA0KICAgICAgICAgICAgICAgICAgICBmb3JtYXRDKGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGVkdC5zaHAkTWludXRlb2ZEYSkpLCB3aWR0aCA9IDIsIGZsYWcgPSAiMCIpLCBzZXAgPSAiIikNCiAgZWR0LnNocCR0aW1lIDwtIHN0cnB0aW1lKGVkdC50aW1lLCBmb3JtYXQgPSAiJVkvJW0vJWQgJUg6JU0iLCB0ej0iQW1lcmljYS9OZXdfWW9yayIpDQoNCiAgIyBSZWFkIGluIGNvdW50eSBkYXRhIGZyb20gQ2Vuc3VzDQogIGNvdW50aWVzIDwtIHJlYWRPR1IoIkNlbnN1c0NvdW50eS8uIikNCiAgbWRfY291bnRpZXMgPC0gY291bnRpZXNbY291bnRpZXMkU1RBVEVGUCA9PSAyNCxdDQoNCiAgIyBTYXZlIGltcG9ydGVkIHdhemUgYW5kIEVEVCBmaWxlcyBhcyAuUkRhdGEgZm9yIGZhc3RlciBpbXBvcnQgYWZ0ZXIgdGhlIGZpcnN0IHRpbWUNCiAgc2F2ZShmaWxlID0gIkVEVF9XYXplLlJEYXRhIiwgbGlzdCA9IGMoIndhei5zaHAiLCAiZWR0LnNocCIsICJtZF9jb3VudGllcyIpKQ0KfSBlbHNlIHsgbG9hZCgnRURUX1dhemUuUkRhdGEnKSB9DQoNCg0KYGBgDQoNCiMjIyBJbml0aWFsIG1hcHBpbmcgd29yaw0KDQpgYGB7ciBmb3J0Lm1hcCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiMgQ3VycmVudGx5IG5vdCBydW4gLS0gdGhpcyBpcyB0aGUgc3RhcnQgb2YgbWFraW5nIGEgZm9ydGlmaWVkIGRhdGFmcmFtZSBmb3IgZ2dwbG90IG1hcHBpbmcsIHRvIHR1cm4gaW50byBhIHBsb3RseSBtYXAuDQojIEdldCBwb2ludHMgaW4gcG9seWdvbnM6IGV2ZW50cyBpbiBlYWNoIGNvdW50eQ0KcHJvajRzdHJpbmcoZWR0LnNocCkgPC0gcHJvajRzdHJpbmcod2F6LnNocCkgPC0gcHJvajRzdHJpbmcobWRfY291bnRpZXMpDQoNCm1kX3BpcCA8LSBvdmVyKHdhei5zaHAsIG1kX2NvdW50aWVzWywiTkFNRSJdKQ0KDQp3YXouc2hwJE5BTUUgPC0gbWRfcGlwDQoNCm1kX2Jhc2UgPC0gZ2dwbG90KG1kX2NvdW50aWVzKSArIGdlb21fbWFwKGRhdGEgPSBtZF9jb3VudGllcywgbWFwID0gbWRfY291bnRpZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgbWFwX2lkID0gaWQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSkgKw0KICB5bGFiKGxhYmVsPSIiKSArIHhsYWIobGFiZWw9IiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgY29vcmRfbWFwKHByb2plY3Rpb249ImFsYmVycyIsIGxhdCA9IDM5LCBsYXQxID0gNDUpDQpgYGANCg0KYGBge3IgcGxvdGx5bWFwfQ0KY291bnRpZXMgPC0gbWFwX2RhdGEoImNvdW50eSIsICJtYXJ5bGFuZCIpDQoNCndhei5zaHAkdG9vbHRpcHRleHQgPC0gd2l0aCh3YXouc2hwQGRhdGEsIHBhc3RlKGNpdHksIGFsZXJ0X3R5cGUsIHRpbWUsIHNlcCA9ICJcbiIpKQ0Kd2F6LnNocCR0b29sdGlwdGV4dCA8LSBzdWIoIk5BIiwgIiIsIHdhei5zaHAkdG9vbHRpcHRleHQpDQoNCmVkdC5zaHAkdG9vbHRpcHRleHQgPC0gd2l0aChlZHQuc2hwQGRhdGEsIHBhc3RlKENvdW50eSwgSGlnaGVzdEluaiwgdGltZSwgc2VwID0gIlxuIikpDQplZHQuc2hwJHRvb2x0aXB0ZXh0IDwtIHN1YigiTkEiLCAiIiwgZWR0LnNocCR0b29sdGlwdGV4dCkNCg0KDQptYXAucCA8LSBnZ3Bsb3QoKSArDQogIGdndGl0bGUoIjIwMTctMDgtMDEgU3BhdGlhbCBPdmVybGF5IikgKw0KICBnZW9tX3BvbHlnb24oZGF0YSA9IGNvdW50aWVzLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwgZmlsbCA9ICJncmV5ODAiKSArIHRoZW1lX3ZvaWQoKSArDQpjb29yZF9maXhlZCgxLjMpICsNCg0KICBnZW9tX3BvaW50KGRhdGEgPSB3YXouc2hwW2Zvcm1hdCh3YXouc2hwJHRpbWUsICIlZCIpID09ICIwMSIsXUBkYXRhLCAjIDIwMTctMDgtMDEgZmlyc3QNCiAgICAgICAgICAgICBhZXMoDQogICAgICAgICAgICAgICB4ID0gbG9uZ2l0dWRlLCANCiAgICAgICAgICAgICAgIHkgPSBsYXRpdHVkZSwgDQogICAgICAgICAgICAgICBjb2xvciA9IGFsZXJ0X3R5cGUsDQogICAgICAgICAgICAgICAgdGV4dCA9IHRvb2x0aXB0ZXh0KSwNCiAgICAgICAgICAgICBzaGFwZSA9IDE2KSArDQoNCiAgZ2VvbV9wb2ludChkYXRhID0gZWR0LnNocFtmb3JtYXQoZWR0LnNocCR0aW1lLCAiJWQiKSA9PSAiMDEiLF1AZGF0YSwgIyAyMDE3LTA4LTAxIGZpcnN0DQogICAgICAgICAgICAgYWVzKA0KICAgICAgICAgICAgICAgeCA9IEdQU0xvbmdfTmUsIA0KICAgICAgICAgICAgICAgeSA9IEdQU0xhdCwgDQogICAgICAgICAgICAgICB0ZXh0ID0gdG9vbHRpcHRleHQsDQogICAgICAgICAgICAgICBjb2xvciA9ICdFRFQnKSwNCiAgICAgICAgICAgICBzaGFwZSA9IDE2KSArDQogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJXYXplIEFsZXJ0IFR5cGUgYW5kIEVEVCBDcmFzaCIpDQoNCiAgDQpnZ3Bsb3RseShtYXAucCwgdG9vbHRpcCA9ICJ0ZXh0Iiwgd2lkdGggPSAxMDAwKQ0KDQpgYGANCg0KIyMjIEludGVyYWN0aXZlIHRhYmxlIG9mIFdhemUgZXZlbnRzIGJ5IGRheSANCg0KYGBge3IgZnJlcWV2ZW50c30NCiMgbWFrZSBhIHRhYmxlIG9mIGZyZXF1ZW5jeSBvZiBhbGVydF90eXBlIGJ5IGRheQ0KZnJlcS50YWIgPC0gYWdncmVnYXRlKHV1aWQgfiBmb3JtYXQodGltZSwgIiVkIikgKyBhbGVydF90eXBlLA0KICAgICAgICAgIEZVTiA9IGxlbmd0aCwNCiAgICAgICAgICBkYXRhID0gd2F6LnNocEBkYXRhKQ0KDQpkYXRhdGFibGUoZnJlcS50YWIsDQogICAgICAgICAgZmlsdGVyID0gJ3RvcCcsDQogICAgICAgICAgY29sbmFtZXMgPSBjKCJEYXkiID0gMSwgIkFsZXJ0IFR5cGUiID0gMiwgIkNvdW50Ij0gMyksDQogICAgICAgICAgcm93bmFtZXMgPSBGLA0KICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KGRvbSA9ICJmdGlwIikpDQpgYGANCg0KDQojIyMgU3BhdGlvdGVtcG9yYWwgam9pbg0KDQpgYGB7ciBzdGpvaW4sIHdhcm5pbmcgPSBGLCBldmFsID0gVH0gDQoNCiMgZm9yIGVhY2ggRURUIGV2ZW50LCBmaW5kIHRoZSBudW1iZXIgYW5kIGRpc3RhbmNlIGZvciBuZWFyZXN0IG5laWdoYm9ycyBpbiBzcGFjZSBhbmQgdGltZSBmcm9tIFdhemUgZGF0YQ0KZXggPC0gZWR0LnNocEBkYXRhDQoNCmRpc3RicmVha3MgPC0gYygwLCAwLjEsIDAuNSwgMSwgNSwgMTAsIDE1LCAyNSwgNTAsIDEwMCwgMzAwLCAxMDAwKQ0KZGlzdGNvdW50cyA8LSB2ZWN0b3IoKQ0KDQpmb3IoaSBpbiAxOm5yb3coZXgpKXsNCg0KICBkYXRlcmFuZ2VtaW4gPC0gZXhbaSwgJ3RpbWUnXSAtIDIqNjAqNjANCiAgZGF0ZXJhbmdlbWF4IDwtIGV4W2ksICd0aW1lJ10gKyAyKjYwKjYwDQogICAgDQogICMgZmluZCB3YXplIGV2ZW50cyB3aXRoaW4gMyBocnMgb2YgdGhpcyBjcmFzaA0KICANCiAgd3ggPC0gd2F6LnNocFt3YXouc2hwJHRpbWUgPiBkYXRlcmFuZ2VtaW4gJiB3YXouc2hwJHRpbWUgPCBkYXRlcmFuZ2VtYXgsXQ0KICANCiAgaWYobnJvdyh3eCkgPT0wKSB7DQogICAgYiA8LSByZXAoMCwgbGVuZ3RoKGRpc3RicmVha3MpKQ0KICB9IGVsc2Ugew0KICB3X3NwIDwtIFNwYXRpYWxQb2ludHMoY29vcmRzID0gZGF0YS5mcmFtZSh3eCRsb25naXR1ZGUsIHd4JGxhdGl0dWRlKSkNCiAgZV9zcCA8LSBTcGF0aWFsUG9pbnRzKGNvb3JkcyA9IGRhdGEuZnJhbWUoZXhbaSwnR1BTTG9uZ19OZSddLCBleFtpLCdHUFNMYXQnXSkpDQogIA0KICB0MSA8LSBzcERpc3RzKHdfc3AsIGVfc3AsIGxvbmdsYXQgPSBUKSAjIGRpc3RhbmNlIGluIGttIHRvIGVhY2ggZWR0IGV2ZW50DQogIA0KICAjIFN1bSBvZiBldmVudHMgd2l0aCAwLjEgdG8gMTAwIG1pIGluIHZhcmlvdXMgY2h1bmtzDQogIGIgPC0gaGlzdCh0MSwgYnJlYWtzID0gZGlzdGJyZWFrcywgcGxvdCA9IEYpJGNvdW50cw0KICB9DQoNCiAgZGlzdGNvdW50cyA8LSByYmluZChkaXN0Y291bnRzLCBiKQ0KICANCiAgIyBTdW0gb2YgZXZlbnRzIHdpdGhpbiAxIHRvIDEyMCBtaW51dGVzDQogIA0KICB9DQoNCmNvbG5hbWVzKGRpc3Rjb3VudHMpID0gZGlzdGJyZWFrc1syOmxlbmd0aChkaXN0YnJlYWtzKV0NCnJvd25hbWVzKGRpc3Rjb3VudHMpID0gZXgkSUQNCg0KZG0gPC0gbWVsdChkaXN0Y291bnRzKQ0KY29sbmFtZXMoZG0pIDwtIGMoIklEIiwgIkJpbiIsICJDb3VudCIpDQpkbSRCaW4gPC0gYXMuZmFjdG9yKGRtJEJpbikNCg0KZ3AgPC0gZ2dwbG90KGRtKSArIGdlb21faGlzdG9ncmFtKGFlcyh4ID0gQ291bnQpLCBiaW5zID0gNTApICsgZmFjZXRfd3JhcCh+QmluKSArIHlsYWIoIkZyZXF1ZW5jeSIpICsgeGxhYigiQ291bnQgb2YgV2F6ZSBFdmVudHMiKQ0KDQpnZ3Bsb3RseShncCwgd2lkdGggPSAxMDAwLCB0b29sdGlwID0gYygiY291bnQiKSkNCg0KYGBg